package com.ymm.lulutong.mq.consumer;

import com.alibaba.fastjson.JSON;
import com.ymm.lulutong.constants.*;
import com.ymm.lulutong.domain.ShipperNoticeDomainService;
import com.ymm.lulutong.entity.Notice;
import com.ymm.lulutong.entity.OrderOpsLog;
import com.ymm.lulutong.mapper.ShipperOrderOpsLogMapper;
import com.ymm.lulutong.mq.consumer.msg.OrderCancelMsg;
import com.ymm.lulutong.websocket.WebSocket;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Objects;

/**
 * 订单取消 消息消费者
 *
 * @author guorui
 */
@Slf4j
@Component
@RocketMQMessageListener(topic = "${mq.topic.order}", consumerGroup = "${mq.consumer.groupname.order.cancel}", selectorExpression = "cancel", maxReconsumeTimes = 3)
public class OrderCancelMsgConsumer implements RocketMQListener<MessageExt> {
    @Resource
    private ShipperOrderOpsLogMapper shipperOrderOpsLogMapper;

    @Resource
    private WebSocket webSocket;

    @Resource
    private ShipperNoticeDomainService shipperNoticeDomainService;

    @Override
    public void onMessage(MessageExt messageExt) {
        //解析消息内容
        String body = new String(messageExt.getBody(), StandardCharsets.UTF_8);
        OrderCancelMsg orderCancelMsg = JSON.parseObject(body, OrderCancelMsg.class);
        if (Objects.isNull(orderCancelMsg)) {
            log.info("orderConfirmMsg为空！");
            return;
        }
        Long orderId = orderCancelMsg.getOrderId();
        Long shipperId = orderCancelMsg.getShipperId();
        Long cargoId = orderCancelMsg.getCargoId();
        Integer opsType = OrderOpsEnum.CANCEL.getCode();
        if (Objects.isNull(orderId) || Objects.isNull(shipperId) || Objects.isNull(cargoId)) {
            log.info("参数为空！");
            return;
        }
        OrderOpsLog orderOpsLog = new OrderOpsLog();
        orderOpsLog.setShipperId(shipperId);
        orderOpsLog.setOrderId(orderId);
        orderOpsLog.setCargoId(cargoId);
        orderOpsLog.setOpsType(opsType);
        orderOpsLog.setOpsPersonType(orderCancelMsg.getOpsPersonType());
        orderOpsLog.setOpsPersonId(orderCancelMsg.getOpsPersonId());
        orderOpsLog.setCreateTime(new Date());
        orderOpsLog.setUpdateTime(new Date());
        orderOpsLog.setExecutionStatus(MessgeStatusEnum.IN_EXECUTION.getCode());

        //保存到数据库
        try {
            shipperOrderOpsLogMapper.add(orderOpsLog);
        } catch (Exception e) {
            e.printStackTrace();
            if (!Objects.isNull(shipperOrderOpsLogMapper.getLogIdByShipperIdAndOrderIdAndOpsType(shipperId, orderId, opsType))) {
                log.info(orderOpsLog.getLogId() + "消息已经被消费过");
                return;
            } else {
                log.info("数据库错误");
                //重试
                throw e;
            }
        }

        //投递通知
        try {
            Notice notice = new Notice();
            notice.setShipperId(shipperId);
            if (orderCancelMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SYSTEM.getCode())) {
                notice.setContent("您的订单被系统取消！");
            } else if (orderCancelMsg.getOpsPersonType().equals(OpsPersonTypeEnum.AGENT.getCode())) {
                notice.setContent("您的订单被客服取消！");
            } else if (orderCancelMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SHIPPER.getCode())) {
                notice.setContent("订单取消成功！");
            }
            notice.setFromPersonType(NoticeFromPersonEnum.SYSTEM.getCode());
            notice.setFromPersonId(0L);
            notice.setNoticeType(NoticeTypeEnum.ORDER_NOTICE.getCode());
            notice.setAdditionalInformation("{\"orderId\":" + orderId + ", \"cargoId\":" + cargoId + "}");
            shipperNoticeDomainService.saveNotice(notice);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //WebSocket通知
        try {
            String content = null;
            if (orderCancelMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SYSTEM.getCode())) {
                content = "您的订单被系统取消！";
            } else if (orderCancelMsg.getOpsPersonType().equals(OpsPersonTypeEnum.AGENT.getCode())) {
                content = "您的订单被客服取消！";
            } else if (orderCancelMsg.getOpsPersonType().equals(OpsPersonTypeEnum.SHIPPER.getCode())) {
                content = "订单取消成功！";
            }
            webSocket.sendOnMessage(shipperId, content);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //设置业务执行状态为完成
        shipperOrderOpsLogMapper.updateExecutionStatusByLogId(orderOpsLog.getLogId(), MessgeStatusEnum.COMPLETED.getCode());

    }
}
